home *** CD-ROM | disk | FTP | other *** search
- /*
- * FILE
- * initsplan
- *
- * DESCRIPTION
- * Target list, qualification, joininfo initialization routines
- *
- */
-
- /* RcsId("$Header: /private/postgres/src/planner/plan/RCS/initsplan.c,v 1.23 1992/07/15 04:33:11 mer Exp $"); */
-
- /*
- * EXPORTS
- * initialize-targetlist
- * initialize-qualification
- * initialize-join-clause-info
- *
- * NOTES
- * These routines are called by(subplanner) and modify global state of
- * the planner(adding entries to *query-relation-list* or modifying an
- * existing entry).
- */
-
- #include "tmp/c.h"
-
- #include "nodes/pg_lisp.h"
- #include "nodes/plannodes.h"
- #include "nodes/plannodes.a.h"
- #include "nodes/relation.h"
- #include "nodes/relation.a.h"
-
- #include "utils/lsyscache.h"
-
- #include "planner/internal.h"
- #include "planner/clause.h"
- #include "planner/clauses.h"
- #include "planner/clausesel.h"
- #include "planner/initsplan.h"
- #include "planner/joininfo.h"
- #include "planner/relnode.h"
- #include "planner/tlist.h"
- #include "planner/var.h"
-
- extern bool _enable_mergesort_;
- extern bool _enable_hashjoin_;
- extern int Quiet;
-
- /* ============
- * TARGET LISTS
- * ============
- */
-
- /*
- * initialize-targetlist
- *
- * Creates rel nodes for every relation mentioned in the target list
- * 'tlist' (if a node hasn't already been created) and adds them to
- * *query-relation-list*. Creates targetlist entries for each member of
- * 'tlist' and adds them to the tlist field of the appropriate rel node.
- *
- * Returns nothing.
- *
- */
-
- /* .. subplanner */
-
- void
- initialize_targetlist(tlist)
- List tlist ;
- {
- List tlist_vars = LispNil;
- List xtl = LispNil;
- List tvar = LispNil;
-
- #ifdef NO_PLEASE
- if(!Quiet) {
- lispDisplay(tlist,0);
- printf("\n");
- fflush(stdout);
- }
- #endif NO_PLEASE
-
- foreach (xtl,tlist) {
- TLE entry;
- (LispValue)entry = CAR(xtl);
-
- #ifdef NO_PLEASE
- if(!Quiet) {
- lispDisplay(entry,0);
- fflush(stdout);
- }
- #endif NO_PLEASE
- tlist_vars = nconc(tlist_vars,pull_var_clause( (LispValue)
- get_expr(entry) ));
- }
-
- foreach (tvar, tlist_vars) {
- Var var;
- Index varno;
- Rel result;
-
- var = (Var)CAR(tvar);
- varno = get_varno(var);
- result = get_rel(lispInteger(varno));
-
- add_tl_element(result,var,LispNil);
- }
-
- } /* function end */
-
- /* ==============
- * QUALIFICATIONS
- * ==============
- */
-
- /*
- * initialize-qualification
- *
- * Initializes ClauseInfo and JoinInfo fields of relation entries for all
- * relations appearing within clauses. Creates new relation entries if
- * necessary, adding them to *query-relation-list*.
- *
- * Returns nothing of interest.
- *
- */
-
- /* .. initialize-qualification, subplanner */
-
- void
- initialize_qualification(clauses)
- LispValue clauses ;
- {
- LispValue clause = LispNil;
-
- foreach (clause, clauses) {
- if(consp(CAR(clause)) && IsA(CAR(clause),Func))
- initialize_qualification(get_funcargs(CAR(clause)));
- else
- if(consp(CAR(clause)) && IsA(CAR(clause),Oper))
- initialize_qualification(get_opargs(CAR(clause)));
- add_clause_to_rels(CAR(clause));
- }
- } /* function end */
-
- /*
- * add-clause-to-rels
- *
- * Add clause information to either the 'ClauseInfo' or 'JoinInfo' field
- * of a relation entry(depending on whether or not the clause is a join)
- * by creating a new ClauseInfo node and setting appropriate fields
- * within the nodes.
- *
- * Returns nothing of interest.
- *
- */
-
- /* .. initialize-qualification */
-
- void
- add_clause_to_rels(clause)
- LispValue clause ;
- {
-
- /* Retrieve all relids and vars contained within the clause in the form */
- /* ((relid relid ...) (var var ...)) */
-
- LispValue relids_vars = clause_relids_vars(clause);
- LispValue relids = nth(0,relids_vars);
- LispValue vars = nth(1,relids_vars);
-
- if(relation_level_clause_p(clause))
- /*
- * Ignore quals containing relation level clauses, but place the vars
- * in the target list so their values can be referenced later.
- */
- add_vars_to_rels(vars,LispNil);
- else {
- CInfo clauseinfo = RMakeCInfo();
- set_clause(clauseinfo,clause);
- set_notclause(clauseinfo,contains_not(clause));
- set_selectivity(clauseinfo,0);
- set_indexids(clauseinfo,LispNil);
- set_mergesortorder(clauseinfo,(MergeOrder)NULL);
- set_hashjoinoperator(clauseinfo,(ObjectId)0);
-
- if(1 == length(relids)) {
-
- /* There is only one relation participating in 'clause', */
- /* so 'clause' must be a restriction clause. */
- /* XXX - let form, maybe incorrect */
- Rel rel = get_rel(CAR(relids));
- set_clauseinfo(rel,cons((LispValue)clauseinfo,
- (LispValue)get_clauseinfo(rel)));
- }
- else {
- /* 'clause' is a join clause, since there is more than one */
- /* atom in the relid list. */
-
- /*
- * XXX If we have a func clause set selectivity to 1/3, really
- * need a true selectivity function.
- */
- if (is_funcclause(clause))
- {
- set_selectivity(clauseinfo,(Cost)0.3333333);
- }
- else
- {
- set_selectivity(clauseinfo,compute_clause_selec(clause,
- LispNil));
- }
- add_join_clause_info_to_rels(clauseinfo,relids);
- add_vars_to_rels(vars,relids);
- }
- }
- } /* function end */
-
- /*
- * add-join-clause-info-to-rels
- *
- * For every relation participating in a join clause, add 'clauseinfo' to
- * the appropriate joininfo node(creating a new one and adding it to the
- * appropriate rel node if necessary).
- *
- * 'clauseinfo' describes the join clause
- * 'join-relids' is the list of relations participating in the join clause
- *
- * Returns nothing.
- *
- */
-
- /* .. add-clause-to-rels */
-
- void
- add_join_clause_info_to_rels(clauseinfo,join_relids)
- CInfo clauseinfo;
- List join_relids ;
- {
- LispValue join_relid = LispNil;
- foreach (join_relid, join_relids) {
- JInfo joininfo =
- find_joininfo_node(get_rel(CAR(join_relid)),
- LispRemove(CAR(join_relid),join_relids));
- set_jinfoclauseinfo(joininfo,
- lispCons((LispValue)clauseinfo,
- get_jinfoclauseinfo(joininfo)));
-
- }
- } /* function end */
-
- /*
- * add-vars-to-rels
- *
- * For each variable appearing in a clause,
- * (1) If a targetlist entry for the variable is not already present in
- * the appropriate relation's target list, add one.
- * (2) If a targetlist entry is already present, but the var is part of a
- * join clause, add the relids of the join relations to the JoinList
- * entry of the targetlist entry.
- *
- * 'vars' is the list of var nodes
- * 'join-relids' is the list of relids appearing in the join clause
- * (if this is a join clause)
- *
- * Returns nothing.
- *
- */
-
- /* .. add-clause-to-rels */
-
- void
- add_vars_to_rels(vars,join_relids)
- List vars,join_relids ;
- {
- Var var;
- LispValue temp = LispNil;
- Rel rel = (Rel)NULL;
- LispValue tlistentry = LispNil;
- LispValue other_join_relids = LispNil;
-
- foreach (temp, vars) {
- var = (Var)CAR(temp);
- rel = get_rel(lispInteger(get_varno(var)));
- tlistentry = tlistentry_member(var,get_targetlist(rel));
- other_join_relids = LispRemove(lispInteger(get_varno(var)),
- join_relids);
- if(null(tlistentry))
- /* add a new entry */
- add_tl_element(rel,var,other_join_relids);
- else
- if(get_joinlist(tlistentry)) {
- set_joinlist(tlistentry,
- /* modify an existing entry */
- LispUnion(get_joinlist(tlistentry),
- other_join_relids));
- }
- }
- } /* function end */
-
- /* ========
- * JOININFO
- * ========
- */
-
- /*
- * initialize-join-clause-info
- *
- * Set the MergeSortable or HashJoinable field for every joininfo node
- * (within a rel node) and the MergeSortOrder or HashJoinOp field for
- * each clauseinfo node(within a joininfo node) for all relations in a
- * query.
- *
- * Returns nothing.
- *
- */
-
- /* .. subplanner */
-
- void
- initialize_join_clause_info(rel_list)
- LispValue rel_list ;
- {
- LispValue x;
- Rel rel;
- LispValue y;
- JInfo joininfo;
- LispValue z;
- CInfo clauseinfo;
- LispValue clause;
- foreach (x, rel_list) {
- rel = (Rel)CAR(x);
- foreach (y, get_joininfo(rel)) {
- joininfo = (JInfo)CAR(y);
- foreach (z, get_jinfoclauseinfo(joininfo)) {
- clauseinfo = (CInfo)CAR(z);
- clause = (LispValue)get_clause(clauseinfo);
- if( join_clause_p(clause) ) {
- MergeOrder sortop = (MergeOrder)NULL;
- ObjectId hashop = (ObjectId)NULL;
-
- if( _enable_mergesort_ )
- sortop = mergesortop(clause);
- if( _enable_hashjoin_ )
- hashop = hashjoinop(clause);
-
- if( sortop) {
- set_mergesortorder(clauseinfo, sortop);
- set_mergesortable(joininfo,true);
- }
- if( hashop) {
- set_hashjoinoperator(clauseinfo,hashop);
- set_hashjoinable(joininfo,true);
- }
- }
- }
- }
- }
- } /* function end */
-
- /*
- * mergesortop === MERGE
- *
- * Returns the mergesort operator of an operator iff 'clause' is
- * mergesortable, i.e., both operands are single vars and the operator is
- * a mergesortable operator.
- *
- */
- MergeOrder
- mergesortop(clause)
- LispValue clause;
- {
- LispValue sortops = op_mergesortable(get_opno((Oper)get_op(clause)),
- get_vartype(get_leftop(clause)),
- get_vartype(get_rightop(clause)));
- if( consp(sortops) ) {
- return(MakeMergeOrder(get_opno((Oper)get_op(clause)),
- (ObjectId)nth(0,sortops),
- (ObjectId)nth(1,sortops),
- get_vartype(get_leftop(clause)),
- get_vartype(get_rightop(clause))));
- }
- else
- return(NULL);
- } /* function end */
-
- /*
- * hashjoinop === HASH
- *
- * Returns the hashjoin operator of an operator iff 'clause' is
- * hashjoinable, i.e., both operands are single vars and the operator is
- * a hashjoinable operator.
- *
- */
-
- /* .. initialize-join-clause-info */
-
- ObjectId
- hashjoinop(clause)
- LispValue clause ;
- {
- return(op_hashjoinable(get_opno((Oper)get_op(clause)),
- get_vartype(get_leftop(clause)),
- get_vartype(get_rightop(clause))));
- }
-